/* ************************************************************************* */
/*																			 */
/* Standard application Shell  - C Version									 */
/* By: Keith Rollin and Jim Mensch											 */
/*																			 */
/*		v1.0B1	Mensch	First Pass											 */
/*		v1.0B2	Mensch	Included editorial corrections						 */
/*		v1.0B3	Kaar	Converted to 'C'. Calls DeskStartup() and			 */
/*						FixAppleMenu().										 */
/*		v1.0B4  Kaar	Added comments and error checking.					 */
/*		v1.0	Kaar	First Release										 */
/*		v1.0.1	Mensch	Removed Desktop call								 */
/*																			 */
/* ************************************************************************* */
/*********************************************************************
*                                                                    *
*             Apple IIGS Source Code Sampler, Volume I               *
*                                                                    *
*             Copyright (c) Apple Computer, Inc. 1988                *
*                       All Rights Reserved                          *
*                                                                    *
*            Written by Apple II Developer Tech Support              *
*                                                                    *
*                                                                    *
*                                                                    *
*  ----------------------------------------------------------------  *
*                                                                    *
*     This program and its derivatives are licensed only for         *
*     use on Apple computers.                                        *
*                                                                    *
*     Works based on this program must contain and                   *
*     conspicuously display this notice.                             *
*                                                                    *
*     This software is provided for your evaluation and to           *
*     assist you in developing software for the Apple IIGS           *
*     computer.                                                      *
*                                                                    *
*     DISCLAIMER OF WARRANTY                                         *
*                                                                    *
*     THE SOFTWARE IS PROVIDED "AS IS" WITHOUT                       *
*     WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,               *
*     WITH RESPECT TO ITS MERCHANTABILITY OR ITS FITNESS             *
*     FOR ANY PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO             *
*     THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH            *
*     YOU.  SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU (AND            *
*     NOT APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE)               *
*     ASSUME THE ENTIRE COST OF ALL NECESSARY SERVICING,             *
*     REPAIR OR CORRECTION.                                          *
*                                                                    *
*     Apple does not warrant that the functions                      *
*     contained in the Software will meet your requirements          *
*     or that the operation of the Software will be                  *
*     uninterrupted or error free or that defects in the             *
*     Software will be corrected.                                    *
*                                                                    *
*     SOME STATES DO NOT ALLOW THE EXCLUSION                         *
*     OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY              *
*     NOT APPLY TO YOU.  THIS WARRANTY GIVES YOU SPECIFIC            *
*     LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS                *
*     WHICH VARY FROM STATE TO STATE.                                *
*                                                                    *
*                                                                    *
*********************************************************************/

#include <types.h>     
#include <prodos.h>                             
#include <misctool.h>                            
#include <quickdraw.h>                         
#include <window.h>
#include <memory.h>
#include <dialog.h>
#include <menu.h>
#include <control.h>
#include <desk.h>
#include <event.h>
#include <lineedit.h>
#include <misctool.h>
#include <locator.h>
#include <Stdfile.h>
#include <qdaux.h>
#include <print.h>
#include <font.h>
#include <intmath.h>
#include <scrap.h>
#include <texttool.h>

extern int _toolErr;


/* ************************************************************************* */
/*																			 */
/* Standard Global data here												 */
/*																			 */
/* ************************************************************************* */

char TitleString[]	= "\pApple IIgs Shell Application  -  C Version";
char AutString[]	= "\pBy Rollin & Mensch ©1988 Apple Computer";
char VersString[]	= "\pVersion: 1.0                          June 17, 1988";

int MyID;
int ThisMode = mode640;                           /* init mode = 640 */
#define ScreenWidth 640

int ToolTable[] = {6,				/* number of tools to load in */
                14, 0x0100,			/* Window Manager */
                15, 0x0100,			/* Menu Manager */
                16, 0x0100,			/* Control Mnager */
                20, 0x0100,			/* Line Edit */
                21, 0x0100,			/* Dialog Manager */
                22, 0x0100			/* Scrap Manager  */
				
			/*	18, 0x0100,			/* QD Aux */
			/*	19, 0x0100,			/* Print Manager */
			/*	23, 0x0100,			/* Standard File */
			/*	25, 0x0100,			/* Note Synthesizer */
			/*	27, 0x0100,			/* Font Manager */
			/*	28, 0x0100,			/* List manager */
			/*	29, 0x0100,			/* ACE Tools */
			/*	32, 0x0100,			/* MIDI Tools */
				};

/* The following is used when it is time to quit this application. When the	*/
/* user selects "Quit" from the File menu, the program sets the QuitFlag	*/
/* to a non-zero value. This is the condition that tells the main event		*/
/* loop to stop and return to the calling procedure.						*/

boolean QuitFlag;

/* The following is the record that is used by TaskMaster to return events.	*/
/* It is similar to a regular event record, except that there are two		*/
/* additional fields at the end. The first is used to convey some TaskMaster*/
/* specific data back to the application. The second is called the TaskMask	*/
/* and is used to tell TaskMaster what situations to handle. In this shell,	*/
/* we tell TaskMaster to handle everything by setting all currently defined	*/
/* bits to 1.																*/
		
WmTaskRec EventRec = {				/* Data block to hold event records */
		0,
		0L,
		0L,
		0,0,
		0,
		0L,
		0x0000FFFFL};				/* Let TaskMaster do it all! */


/* We take the easy way out and use the Dialog Manager call NoteAlert() to	*/
/* display our About box. We provide the strings and buttons, and it puts	*/
/* it all in a window, adds an icon, and handles a events until the OK		*/
/* button is pressed.														*/

ItemTemplate OKButton = {
		ok,							/* item number (predefined in Dialog.h) */
		50,500,65,550,				/* bounding rectangle */
		buttonItem,					/* simple button type */
		"\pOK",						/* Pointer to its name */
		0,							/* initial value */
		0,							/* item flag (invisibility, etc.) */
		NULL};						/* pointer to color table (NULL=Default) */

ItemTemplate AboutTitle = {
		2,
		10,100,20,550,
		statText+itemDisable,
		TitleString,
		0,
		0,
		NULL};

ItemTemplate AboutAut = {
		3,
		25,100,35,550,
		statText+itemDisable,
		AutString,
		0,
		0,
		NULL};

ItemTemplate AboutVers = {
		4,
		40,100,50,550,
		statText+itemDisable,
		VersString,
		0,
		0,
		NULL};

AlertTemplate AboutBox = {
		30,30,100,590,				/* for 320 mode, use 30,30,100,290 */
		1,							/* This is Alert #1 */
		0x80,0x80,0x80,0x80,		/* Alert stages - all silent */
		&OKButton,					/* Ptr to OK button item */
		&AboutTitle,				/* Ptr to name of the program */
		&AboutAut,					/* Ptr to name of the author */
		&AboutVers,					/* Ptr to version number/date */
		NULL};						/* Long $0 to end the list */


/* ************************************************************************* */
/*																			 */
/* Application specific data appears here									 */
/*																			 */
/* ************************************************************************* */


/* ************************************************************************* */
/*																			 */
/* This is an array or characters used to define the menus. Each line starts */
/* off with an identifying character as defined by the Menu Manager Chapter. */
/* It then contains either a Menu Title or Menu Item string, followed by a   */
/* backslash (\\) and any modifiers and ID numbers. Each line is then term-  */
/* inated with a carriage return (\r).										 */
/*																			 */
/* Our sample programs use menus that start at 250. The Edit menu items are  */
/* entered first to conform to the menu manager documentation. The About     */
/* and Quit menu items use IDs 256 and 257 as a convention.					 */
/*																			 */
/* ************************************************************************* */

#define Num_Menus 3

char *Menus[] = {
"$$  Edit  \\DN3\r\
--Undo\\V*ZzN250\r\
--Cut\\*XxN251\r\
--Copy\\*CcN252\r\
--Paste\\V*VvN253\r\
--Clear\\N254\r",

"$$  File  \\N2\r\
--Close\\DVN255\r\
--Quit\\*QqN257\r",

"$$@\\XN1\r\
--About C Shell...\\VN256\r"};


char **y,*z;			/* ZPHandle and ZPPointer */


/* ************************************************************************* */
/*																			 */
/* This is the core of the program. It simply calls all the other routines   */
/* in order.																 */
/*																			 */
/* ************************************************************************* */
main()
{
	InitTools();			/* initialize tools */
	InitApp();				/* initialize application specific stuff */
	ShowCursor();
	EventLoop();			/* do your stuff */
	ShutDownApp();			/* until user wants to  */
	ShutDownTools();		/*   do something else!   */
}


/* ************************************************************************* */
/*																			 */
/* ErrorCheck - Called to InitTools to check for startup errors.			 */
/*																			 */
/* ************************************************************************* */

char DeathMsg[] = "Fatal error $0000 has occurred at 0000. Press any key to exit:";

void ErrorCheck(where)
	int where;
{
      if (_toolErr)
     {
       Int2Hex(_toolErr,DeathMsg + 13 ,4);	/* Stick error # into a string */
       Int2Hex(where,DeathMsg + 34 ,4);	/* Stick location # into a string */
	   GrafOff();							/* Turn off Super Hires */
	   WriteCString(DeathMsg);				/* Print the error message */
	   SysBeep();							/* Danger, Will Robinson!!! */
	   ReadChar(0);							/* Pause for a character */
	   ShutDownTools();						/* ShutDown my Tools */
	   exit(1);								/* Run like a coward */
     }
}


/* ************************************************************************* */
/*																			 */
/* InitTools - This routine start up all the tools that will be needed by    */
/* your application.														 */
/*																			 */
/* ************************************************************************* */

#define QDDPage		0
#define EMDPage		0x0300	/* QDDPage+0x0300 */
#define CtlDPage	0x0400	/* EMDPage+0x0100 */
#define MenuDPage	0x0500	/* CtlDPage+0x0100 */
#define LEDPage		0x0600	/* MenuDPage+0x0100 */
#define ToolDPSize	0x0700L	/* LEDPage+0x0100 - 'L' forces to 32 bit value */

InitTools()
{
	TLStartUp();								/* for calling tools */
	ErrorCheck(1);								/* Make sure all is OK      */
	MyID = MMStartUp();							/* ID for all transactions */
	ErrorCheck(2);								/* Make sure all is OK      */
	MTStartUp();								/* Misc. Tools  */
	ErrorCheck(3);								/* Make sure all is OK      */
	
	y = NewHandle(ToolDPSize,
				MyID,							/* put it to my name    */
				attrLocked+attrFixed+attrPage+attrBank,
				0L);
	ErrorCheck(4);								/* Make sure all is OK      */
	z = *y;										/* deref handle     */
	
	LoadTools(ToolTable);
	ErrorCheck(5);								/* Make sure all is OK      */
	
	QDStartUp((int) z + QDDPage,ThisMode,0,MyID);
	ErrorCheck(6);								/* Make sure all is OK      */
	
	EMStartUp((int) z + EMDPage,20,0,ScreenWidth,0,200,MyID);
	ErrorCheck(7);								/* Make sure all is OK      */
	
	WindStartUp(MyID);
	ErrorCheck(8);								/* Make sure all is OK      */
	
	CtlStartUp(MyID,(int) z + CtlDPage);
	ErrorCheck(9);								/* Make sure all is OK      */
	
	MenuStartUp(MyID,(int) z + MenuDPage);
	ErrorCheck(10);								/* Make sure all is OK      */
	
	LEStartUp(MyID,(int) z + LEDPage);
	ErrorCheck(11);								/* Make sure all is OK      */
	
	DialogStartUp(MyID);
	ErrorCheck(12);								/* Make sure all is OK      */
	
	ScrapStartUp();								/* no errors possible from these 2 */
	DeskStartUp();								/* All we need is init'ed now */
	
	/* Insert application specific tools here */
	
	RefreshDesktop(0L);
	
}

/* ************************************************************************* */
/*																			 */
/* ShutDownTools - Shuts down all of the tools started by InitTools().		 */
/*																			 */
/* ************************************************************************* */

ShutDownTools()
{
	DeskShutDown();
	ScrapShutDown();
	DialogShutDown();
	LEShutDown();
	MenuShutDown();
	CtlShutDown();
	WindShutDown();
	EMShutDown();
	QDShutDown();
	MTShutDown();
	
	DisposeHandle(y);
	
	MMShutDown(MyID);
	TLShutDown();
}


/* ************************************************************************* */
/*																			 */
/* InitApp - This routine is called once after the tools are started. This   */
/* is where you would create your menus, and other objects your program will */
/* need at the very start.													 */
/*																			 */
/* ************************************************************************* */
InitApp()
{
	int i;

	QuitFlag = false;
	
	/* Loop through the array of menu text, and use it to create our menus */
	for (i=0;i < Num_Menus;i++)
		InsertMenu(NewMenu(Menus[i]),0);
	
	FixAppleMenu(1);				/* install NDAs available */
	FixMenuBar();					/* Call CalcMenuSize() for all menus */
	DrawMenuBar();					/* Draw the thing on the screen */
}



/* ************************************************************************* */
/*																			 */
/* ShutDownApp - This routine is called once at the end of your program, but */
/* before the tools are shut down. Take this opportunity to clean up after   */
/* yourself if you need to.													 */
/*																			 */
/* ************************************************************************* */
ShutDownApp()
{
	/* Currently does nothing */
}


/* ************************************************************************* */
/*																			 */
/* InContent - This routine gets called when the user clicks in the content  */
/* region of a window. What happens here is up to you.						 */
/*																			 */
/* ************************************************************************* */
InContent()
{
	/* Currently does nothing */
}


/* ************************************************************************* */
/*																			 */
/* Ignore - called when an event occurs that you don't want/need to handle   */
/*																			 */
/* ************************************************************************* */
Ignore()
{
	/* Does nothing */
}


/* ************************************************************************* */
/*																			 */
/* DoAbout - Show the vanity box until the OK button is hit. Calls			 */
/* NoteAlert to display a dialog box with an icon and handle mouse clicks.   */
/*																			 */
/* ************************************************************************* */
DoAbout()
{
	NoteAlert(&AboutBox,NULL);
}

/* ************************************************************************* */
/*																			 */
/* DoUpdate - This routine is called if you have a window and the Event		 */
/* Manager notices that it needs to have some or all of it redrawn.			 */
/*																			 */
/* ************************************************************************* */
DoUpdate()
{
	/* Put your update routine here */
}


/* ************************************************************************* */
/*																			 */
/* DoQuit - Set the quit flag. This tells the Event loop to exit.			 */
/*																			 */
/* ************************************************************************* */
DoQuit()
{
	QuitFlag = true;
}


/* ************************************************************************* */
/*																			 */
/* MenuSelect - Called when TaskMaster returns a menu event. This routine	 */
/* takes the menu item that was hit and calculates an offset into the menu	 */
/* dispatch table. It then calls that routine.								 */
/*																			 */
/* ************************************************************************* */
WordProcPtr Routines[] = {
	(WordProcPtr) Ignore,		/* Undo */
	(WordProcPtr) Ignore,		/* Cut */
	(WordProcPtr) Ignore,		/* Copy */
	(WordProcPtr) Ignore,		/* Paste */
	(WordProcPtr) Ignore,		/* Clear */
	(WordProcPtr) Ignore,		/* Close */
	(WordProcPtr) DoAbout,		/* Bring up the vanity box */
	(WordProcPtr) DoQuit		/* Set the quit flag */
	};
	
DoMenuSelect()
{
	/* The menu ID of the item selected is in 'wmTaskData'. Since these IDs	*/
	/* start at 250, subtract 250 from the ID to turn it into an index. This*/
	/* index is used to call a routine in a table of routines. */
	
	(*Routines[EventRec.wmTaskData-250])();
	
	/* The routine has been called. Unhilite the menu and return to the Main*/
	/* Event Loop. */
	
	HiliteMenu(0,*(word *)((Pointer)(((long)&EventRec.wmTaskData)+2)));
}


/* ************************************************************************* */
/*																			 */
/* EventLoop - This routine is the heart of your application. It is repeat-	 */
/* edly called and when the user selects/operates something, it dispatches   */
/* to a routine to do the proper thing.										 */
/*																			 */
/* ************************************************************************* */
EventLoop()
{
	word theTask;
	
	do {
	theTask = TaskMaster(everyEvent,&EventRec);	/* Get event from TaskMaster */
	switch (theTask) {					/* switch on the event type. */
		case updateEvt:					/* Handle updates. */
			DoUpdate();
			break;						/* break out of 'switch' statement */
		case wInMenuBar:				/* Handle selections in Special */
		case wInSpecial:				/* and normal menu item selects */
			DoMenuSelect();
			break;						/* break out of 'switch' statement */
		case wInContent:				/* Handle a click in the content */
			InContent();				/* region. */
			break;						/* break out of 'switch' statement */
		}
	} while (!QuitFlag);					/* Loop until "Quit" is selected */
}